import { expect, use } from "chai";

import { block, script, scriptExtension } from "@fontra/core/unicode-scripts-blocks.js";

import { parametrize } from "./test-support.js";

describe("unicode-script tests", () => {
  const scriptTestCases = [
    { codePoint: "a".codePointAt(0), scriptCode: "Latn" },
    { codePoint: 0, scriptCode: "Zyyy" },
    { codePoint: 0x0378, scriptCode: "Zzzz" },
    { codePoint: 0x10ffff, scriptCode: "Zzzz" },
    // these were randomly sampled, one character per script
    { codePoint: 0x1e918, scriptCode: "Adlm" },
    { codePoint: 0x1170d, scriptCode: "Ahom" },
    { codePoint: 0x145a0, scriptCode: "Hluw" },
    { codePoint: 0x0607, scriptCode: "Arab" },
    { codePoint: 0x056c, scriptCode: "Armn" },
    { codePoint: 0x10b27, scriptCode: "Avst" },
    { codePoint: 0x1b41, scriptCode: "Bali" },
    { codePoint: 0x168ad, scriptCode: "Bamu" },
    { codePoint: 0x16add, scriptCode: "Bass" },
    { codePoint: 0x1be5, scriptCode: "Batk" },
    { codePoint: 0x09f3, scriptCode: "Beng" },
    { codePoint: 0x11c5b, scriptCode: "Bhks" },
    { codePoint: 0x3126, scriptCode: "Bopo" },
    { codePoint: 0x1103b, scriptCode: "Brah" },
    { codePoint: 0x2849, scriptCode: "Brai" },
    { codePoint: 0x1a0a, scriptCode: "Bugi" },
    { codePoint: 0x174e, scriptCode: "Buhd" },
    { codePoint: 0x18ee, scriptCode: "Cans" },
    { codePoint: 0x102b7, scriptCode: "Cari" },
    { codePoint: 0x1053d, scriptCode: "Aghb" },
    { codePoint: 0x11123, scriptCode: "Cakm" },
    { codePoint: 0xaa1f, scriptCode: "Cham" },
    { codePoint: 0xab95, scriptCode: "Cher" },
    { codePoint: 0x1f0c7, scriptCode: "Zyyy" },
    { codePoint: 0x2c85, scriptCode: "Copt" },
    { codePoint: 0x12014, scriptCode: "Xsux" },
    { codePoint: 0x1082e, scriptCode: "Cprt" },
    { codePoint: 0xa686, scriptCode: "Cyrl" },
    { codePoint: 0x10417, scriptCode: "Dsrt" },
    { codePoint: 0x093e, scriptCode: "Deva" },
    { codePoint: 0x1bc4b, scriptCode: "Dupl" },
    { codePoint: 0x1310c, scriptCode: "Egyp" },
    { codePoint: 0x1051c, scriptCode: "Elba" },
    { codePoint: 0x2da6, scriptCode: "Ethi" },
    { codePoint: 0x10ad, scriptCode: "Geor" },
    { codePoint: 0x2c52, scriptCode: "Glag" },
    { codePoint: 0x10343, scriptCode: "Goth" },
    { codePoint: 0x11371, scriptCode: "Gran" },
    { codePoint: 0x03d0, scriptCode: "Grek" },
    { codePoint: 0x0aaa, scriptCode: "Gujr" },
    { codePoint: 0x0a4c, scriptCode: "Guru" },
    { codePoint: 0x23c9f, scriptCode: "Hani" },
    { codePoint: 0xc259, scriptCode: "Hang" },
    { codePoint: 0x1722, scriptCode: "Hano" },
    { codePoint: 0x108f5, scriptCode: "Hatr" },
    { codePoint: 0x05c2, scriptCode: "Hebr" },
    { codePoint: 0x1b072, scriptCode: "Hira" },
    { codePoint: 0x10847, scriptCode: "Armi" },
    { codePoint: 0x033a, scriptCode: "Zinh" },
    { codePoint: 0x10b66, scriptCode: "Phli" },
    { codePoint: 0x10b4b, scriptCode: "Prti" },
    { codePoint: 0xa98a, scriptCode: "Java" },
    { codePoint: 0x110b2, scriptCode: "Kthi" },
    { codePoint: 0x0cc6, scriptCode: "Knda" },
    { codePoint: 0x3337, scriptCode: "Kana" },
    { codePoint: 0xa915, scriptCode: "Kali" },
    { codePoint: 0x10a2e, scriptCode: "Khar" },
    { codePoint: 0x17aa, scriptCode: "Khmr" },
    { codePoint: 0x11225, scriptCode: "Khoj" },
    { codePoint: 0x112b6, scriptCode: "Sind" },
    { codePoint: 0x0ed7, scriptCode: "Laoo" },
    { codePoint: 0xab3c, scriptCode: "Latn" },
    { codePoint: 0x1c48, scriptCode: "Lepc" },
    { codePoint: 0x1923, scriptCode: "Limb" },
    { codePoint: 0x1071d, scriptCode: "Lina" },
    { codePoint: 0x100ec, scriptCode: "Linb" },
    { codePoint: 0xa4e9, scriptCode: "Lisu" },
    { codePoint: 0x10284, scriptCode: "Lyci" },
    { codePoint: 0x10926, scriptCode: "Lydi" },
    { codePoint: 0x11161, scriptCode: "Mahj" },
    { codePoint: 0x0d56, scriptCode: "Mlym" },
    { codePoint: 0x0856, scriptCode: "Mand" },
    { codePoint: 0x10af0, scriptCode: "Mani" },
    { codePoint: 0x11cb0, scriptCode: "Marc" },
    { codePoint: 0x11d28, scriptCode: "Gonm" },
    { codePoint: 0xabdd, scriptCode: "Mtei" },
    { codePoint: 0x1e897, scriptCode: "Mend" },
    { codePoint: 0x109b0, scriptCode: "Merc" },
    { codePoint: 0x10993, scriptCode: "Mero" },
    { codePoint: 0x16f5d, scriptCode: "Plrd" },
    { codePoint: 0x1160b, scriptCode: "Modi" },
    { codePoint: 0x18a8, scriptCode: "Mong" },
    { codePoint: 0x16a48, scriptCode: "Mroo" },
    { codePoint: 0x1128c, scriptCode: "Mult" },
    { codePoint: 0x105b, scriptCode: "Mymr" },
    { codePoint: 0x108af, scriptCode: "Nbat" },
    { codePoint: 0x19b3, scriptCode: "Talu" },
    { codePoint: 0x1143d, scriptCode: "Newa" },
    { codePoint: 0x07f4, scriptCode: "Nkoo" },
    { codePoint: 0x1b192, scriptCode: "Nshu" },
    { codePoint: 0x169c, scriptCode: "Ogam" },
    { codePoint: 0x1c56, scriptCode: "Olck" },
    { codePoint: 0x10ce9, scriptCode: "Hung" },
    { codePoint: 0x10316, scriptCode: "Ital" },
    { codePoint: 0x10a93, scriptCode: "Narb" },
    { codePoint: 0x1035a, scriptCode: "Perm" },
    { codePoint: 0x103d5, scriptCode: "Xpeo" },
    { codePoint: 0x10a65, scriptCode: "Sarb" },
    { codePoint: 0x10c09, scriptCode: "Orkh" },
    { codePoint: 0x0b60, scriptCode: "Orya" },
    { codePoint: 0x104cf, scriptCode: "Osge" },
    { codePoint: 0x104a8, scriptCode: "Osma" },
    { codePoint: 0x16b12, scriptCode: "Hmng" },
    { codePoint: 0x10879, scriptCode: "Palm" },
    { codePoint: 0x11af1, scriptCode: "Pauc" },
    { codePoint: 0xa869, scriptCode: "Phag" },
    { codePoint: 0x10909, scriptCode: "Phnx" },
    { codePoint: 0x10b81, scriptCode: "Phlp" },
    { codePoint: 0xa941, scriptCode: "Rjng" },
    { codePoint: 0x16c3, scriptCode: "Runr" },
    { codePoint: 0x0814, scriptCode: "Samr" },
    { codePoint: 0xa88c, scriptCode: "Saur" },
    { codePoint: 0x111c8, scriptCode: "Shrd" },
    { codePoint: 0x1045f, scriptCode: "Shaw" },
    { codePoint: 0x115ad, scriptCode: "Sidd" },
    { codePoint: 0x1d8c0, scriptCode: "Sgnw" },
    { codePoint: 0x0db9, scriptCode: "Sinh" },
    { codePoint: 0x110f9, scriptCode: "Sora" },
    { codePoint: 0x11a60, scriptCode: "Soyo" },
    { codePoint: 0x1b94, scriptCode: "Sund" },
    { codePoint: 0xa81f, scriptCode: "Sylo" },
    { codePoint: 0x0740, scriptCode: "Syrc" },
    { codePoint: 0x1714, scriptCode: "Tglg" },
    { codePoint: 0x1761, scriptCode: "Tagb" },
    { codePoint: 0x1965, scriptCode: "Tale" },
    { codePoint: 0x1a32, scriptCode: "Lana" },
    { codePoint: 0xaa86, scriptCode: "Tavt" },
    { codePoint: 0x116a5, scriptCode: "Takr" },
    { codePoint: 0x0b8e, scriptCode: "Taml" },
    { codePoint: 0x1754d, scriptCode: "Tang" },
    { codePoint: 0x0c40, scriptCode: "Telu" },
    { codePoint: 0x07a4, scriptCode: "Thaa" },
    { codePoint: 0x0e42, scriptCode: "Thai" },
    { codePoint: 0x0f09, scriptCode: "Tibt" },
    { codePoint: 0x2d3a, scriptCode: "Tfng" },
    { codePoint: 0x114b0, scriptCode: "Tirh" },
    { codePoint: 0x1038b, scriptCode: "Ugar" },
    { codePoint: 0xa585, scriptCode: "Vaii" },
    { codePoint: 0x118cf, scriptCode: "Wara" },
    { codePoint: 0xa066, scriptCode: "Yiii" },
    { codePoint: 0x11a31, scriptCode: "Zanb" },
    { codePoint: 0x11f00, scriptCode: "Kawi" },
  ];

  parametrize("unicode-script script tests", scriptTestCases, (testData) => {
    expect(script(testData.codePoint)).to.equal(testData.scriptCode);
  });

  const scriptExtensionTestCases = [
    { codePoint: "a".codePointAt(0), scriptCodes: ["Latn"] },
    { codePoint: 0x0, scriptCodes: ["Zyyy"] },

    { codePoint: 0x0378, scriptCodes: ["Zzzz"] },
    { codePoint: 0x10ffff, scriptCodes: ["Zzzz"] },

    { codePoint: "\u0660".codePointAt(0), scriptCodes: ["Arab", "Thaa", "Yezi"] },
    {
      codePoint: "\u0964".codePointAt(0),
      scriptCodes: [
        "Beng",
        "Deva",
        "Dogr",
        "Gong",
        "Gonm",
        "Gran",
        "Gujr",
        "Guru",
        "Knda",
        "Mahj",
        "Mlym",
        "Nand",
        "Onao",
        "Orya",
        "Sind",
        "Sinh",
        "Sylo",
        "Takr",
        "Taml",
        "Telu",
        "Tirh",
      ],
    },
  ];

  parametrize(
    "unicode-script scriptExtension tests",
    scriptExtensionTestCases,
    (testData) => {
      expect(scriptExtension(testData.codePoint)).to.deep.equal(testData.scriptCodes);
    }
  );

  const blockTestCases = [
    { codePoint: 0x00, blockName: "Basic Latin" },
    { codePoint: 0x7f, blockName: "Basic Latin" },
    { codePoint: 0x80, blockName: "Latin-1 Supplement" },
    { codePoint: 0x1c90, blockName: "Georgian Extended" },
    { codePoint: 0x0870, blockName: "Arabic Extended-B" },
    { codePoint: 0x11b00, blockName: "Devanagari Extended-A" },
  ];

  parametrize("unicode-script block tests", blockTestCases, (testData) => {
    expect(block(testData.codePoint)).to.deep.equal(testData.blockName);
  });
});
